﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Linq;
using System.Text;
using NUnit.Framework;

namespace Myotragus.Data.Tests.Benchmark
{
    public class TestComponent
    {
        public string StringProperty { get; set; }
        public int IntProperty { get; set; }
        public object ObjectProperty { get; set; }
    }

    public static class Configuration
    {
        public const int Times = (int)1e3;
    }

    public static class Constants
    {
        public static object[] EmptyIndices = new object[0];
        public static readonly Type TypeOfTestComponent = typeof (TestComponent);
    }

    [TestFixture]
    public class Properties
    {
        private static TestComponent CreateTestComponent()
        {
            return new TestComponent
                {
                    StringProperty = "TestString",
                    IntProperty = 10,
                    ObjectProperty = new object()
                };
        }

        [Test]
        [Repeat(Configuration.Times)]
        public void ReflectionGetValue()
        {
            var target = CreateTestComponent();
            foreach(var prop in Constants.TypeOfTestComponent.GetProperties())
            {
                var value = prop.GetValue(target, Constants.EmptyIndices);
            }
        }

        [Test]
        [Repeat(Configuration.Times)]
        public void ReflectionGetSetValue()
        {
            var target = CreateTestComponent();
            foreach (var prop in Constants.TypeOfTestComponent.GetProperties())
            {
                var value = prop.GetValue(target, Constants.EmptyIndices);
                prop.SetValue(target, value, Constants.EmptyIndices);
            }
        }

        [Test]
        [Repeat(Configuration.Times)]
        public void ComponentModelGetValue()
        {
            var target = CreateTestComponent();
            foreach(var prop in TypeDescriptor.GetProperties(Constants.TypeOfTestComponent).Cast<PropertyDescriptor>())
            {
                var value = prop.GetValue(target);
            }
        }

        [Test]
        [Repeat(Configuration.Times)]
        public void ComponentModelGetSetValue()
        {
            var target = CreateTestComponent();
            foreach (var prop in TypeDescriptor.GetProperties(Constants.TypeOfTestComponent).Cast<PropertyDescriptor>())
            {
                var value = prop.GetValue(target);
                prop.SetValue(target, value);
            }
        }
    }
}
